/*
 * @Author: byron
 * @Date: 2022-01-18 21:56:33
 * @LastEditTime: 2022-02-19 19:56:12
 */

// export default install

import Vue from 'vue'
import component from './message' // 引入上边定义好的message模板

const MessageBox = Vue.extend(component) // 使用Vue.extend来创建一个构造器
let instance
let instances = []
let seed = 0


const CreateMessage = (options = {}) => {
    // 如果当前定时器已开启，说明页面上已经有一个message-box了，则不能再继续创建新的message-box
    // 对options做处理，如果直接传入string，则使其保存在options的message属性上
    if (typeof options === 'string') {
        options = {
            message: options,
        }
    }

    let top = 20
    instances.forEach((item) => {
        top += item.$el.offsetHeight + 10
    })

    // 初始化实例，并将options作为新的data传入，Vue会将options合并到原有的data上，覆盖原有的默认值，但是，在options中没有设置的是不会被改变的
    instance = new MessageBox({
        data: options,
    })
    instance.topStyle = top
    instance.id = ++seed
    instance.onClose = (id) => {
        close(id)
    }

    // 调用$mount方法，将当前实例渲染为真实DOM，生成$el，如果不执行这一步，将拿不到 $el 的值，但是不指定DOM节点接管当前实例
    instance.vm = instance.$mount()
    document.body.appendChild(instance.vm.$el)
    // 实例上的vm就是我们的Vue组件，所以我们可以通过vm访问到当前实例中的所有属性
    instance.vm.visible = true
    instances.push(instance)

    return instance.vm
}

//定义关闭实例方法
let close = function (id) {
    let index = null
    let offsetHeight = null
    instances.forEach((item, i) => {
        if (item.id === id) {
            index = i
            offsetHeight = item.$el.offsetHeight
        }
    })
    instances.splice(index, 1)
    instances.forEach((item, i) => {
        if (i >= index) {
            item.topStyle = item.topStyle - 10 - offsetHeight
        }
    })
};




// 为message增加type链式调用(立即执行函数)
// (
//     function () {
//         [('success', 'error', 'info', 'warning')].forEach((type) => {
//             CreateMessage[type] = function (option) {
//                 CreateMessage({
//                     ...option,
//                     type
//                 })
//             }
//         })
//     }
// )();
CreateMessage['success'] = function (option) {
    CreateMessage({
        ...option,
        type: 'success'
    })
}
CreateMessage['error'] = function (option) {
    CreateMessage({
        ...option,
        type: 'error'
    })
}
CreateMessage['info'] = function (option) {
    CreateMessage({
        ...option,
        type: 'info'
    })
}
CreateMessage['warning'] = function (option) {
    CreateMessage({
        ...option,
        type: 'warning'
    })
}




// 最终抛出一个对象，对象上我们可以使用 install 来扩展Vue的插件
// 当我们的对象上有install方法的时候，它接收第一个参数为Vue
// 为了方便使用，还在当前抛出的对象上定义了一个message方法，为了方便在axios的拦截器中使用
export default {
    CreateMessage,
    install(Vue) {
        Vue.prototype.$message = CreateMessage
    },
}